package blackjack;

import java.util.*;

/**
 * Monta um baralho e disponibiliza para uso
 *
 * @author Guilherme de Lemos
 */
public class Baralho {
    private List<Carta> baralho;
    private List<Carta> descarte;

    /**
     * Cria um baralho padrao de 52 cartas com quatro naipes já embaralhado.
     */
    public Baralho() {
        super();
        baralho = new ArrayList<Carta>();
        List naipe = criarNaipes();
        this.baralho = criarCartas(naipe);
        embaralhar();
        
        descarte = new ArrayList<Carta>();
    }

    /**
     * Cria uma ArrayList de naipes padrão
     *
     * @return ArrayList de naipes
     */
    private List<Naipe> criarNaipes() {
        List<Naipe> naipe = new ArrayList<Naipe>();

        Naipe ouros = new Naipe();
        ouros.setDescricao("Ouros");
        naipe.add(ouros);

        Naipe espadas = new Naipe();
        espadas.setDescricao("Espadas");
        naipe.add(espadas);

        Naipe copas = new Naipe();
        copas.setDescricao("Copas");
        naipe.add(copas);

        Naipe paus = new Naipe();
        paus.setDescricao("Paus");
        naipe.add(paus);

        return naipe;
    }

    /**
     * Cria um ArrayList de cartas (de A a K) combinando com a lista de naipes
     * que foi passada de parâmetro.
     * 
     * @param naipes Lista de naipes a serem usados no baralho
     * @return ArrayList de cartas
     */
    private List<Carta> criarCartas(List<Naipe> naipes) {
        List<Carta> baralho = new ArrayList<Carta>();

        for (Naipe naipe : naipes) {
            for (int i = 1; i <= 13; i++) {
                Carta carta = new Carta();
                //carta.setValor(i);
                switch(i) {
                    case 1:
                        carta.setDescricao("A");
                        carta.setValor(i);
                        break;
                    case 11:
                        carta.setDescricao("J");
                        carta.setValor(10);
                        break;
                    case 12:
                        carta.setDescricao("Q");
                        carta.setValor(10);
                        break;
                    case 13:
                        carta.setDescricao("K");
                        carta.setValor(10);
                        break;
                    default:
                        carta.setDescricao(String.valueOf(i));
                        carta.setValor(i);
                        break;
                }
                carta.setNaipe(naipe);
                baralho.add(carta);
            }
        }
        return baralho;
    }
    
    /**
     * Imprime o baralho na saída padrão.
     */
    public void imprimir() {
        for(Carta c: baralho) {
            System.out.println(c);
        }
    }
    /**
     * Imprime o descarte na saída padrão.
     */
    public void imprimirDescarte() {
        for(Carta c: descarte) {
            System.out.println(c);
        }
    }
    
    /**
     * Embaralha aleatóriamente.
     */
    public void embaralhar() {
        List<Carta> baralhoAleatorio = new ArrayList<Carta>();
        
        java.util.Random gerador = new java.util.Random();
        Set<Integer> ordem = new LinkedHashSet<Integer>();
        while(ordem.size() < this.baralho.size()) {
            ordem.add(gerador.nextInt(this.baralho.size()));
        }
        
        Object[] vOrdem = ordem.toArray();
                        
        for(int i = 0; i < ordem.size(); i++) {
            baralhoAleatorio.add(baralho.get(Integer.parseInt(vOrdem[i].toString())));
        }
        this.baralho = baralhoAleatorio;
    }
    /**
     * Puxa uma carta do topo do baralho.
     * @return 
     */
    public Carta puxar() {
        Carta carta = baralho.get(0);
        descarte.add(carta);
        baralho.remove(0);
        return carta;
    }
}
